#include "list.h"
#include "platform.h"

Ret_Status list_init(list* plist)
{
    if(plist==NULL)
    {
        ERROR("List handle error!\n");
        return FAIL;
    }
    
    plist->data.id=0;
    plist->data.age=0;
    plist->data.name=NULL;
    plist->prev=NULL;
    plist->next=NULL;
    
    return SUCCESS;
}

list* list_createNode(dataEntry* data)
{
    list* node=NULL;
    
    node=(list*)malloc(sizeof(list));
    assert(node!=NULL);
    memset(node,0x0,sizeof(list));
    
    node->data.id=data->id;
    node->data.age=data->age;
    node->data.name=data->name;
    
    DEBUG("[%s]id:%d, age:%d, name:%s\n",__FUNCTION__,node->data.id,node->data.age,node->data.name);
    return node;
}

list* list_findNode(list* plist,uint8 id)
{
    list* node=NULL;
    
    if(plist==NULL)
    {
        ERROR("List is null,please check!\n");
        return NULL;
    }
    
    node=plist;
    while(node!=NULL)
    {
        if(node->data.id == id)
        {
            DEBUG("find node!\n");
            return node;
        }
        node=node->next;
    }
    
    return NULL;
}

/*
* @func:        list_insert()
* @return:      SUCCESS or FAIL
* @descript:    insert data by data id. 
*               It is always inserted by id order from little to bigger 
* @note:        TODO:Be carefully considered inserted in header and tail.
*/
Ret_Status list_insert(list** plist,list* pdata)
{
    list* plistIndex = NULL;
    list* plistNode = NULL;     //swap struct point use.
    
    if(pdata==NULL)
    {
        ERROR("Data is invalid!\n");
        return FAIL;
    }
    
    if(*plist == NULL)
    {
        DEBUG("List empty,create it!\n");
        plistNode = list_createNode(&(pdata->data));
        assert(NULL != plistNode);
        *plist = plistNode;
        (*plist)->prev = (*plist)->next = NULL;
        return SUCCESS;
    }
    
    if(NULL != list_findNode(*plist,pdata->data.id))
    {
        DEBUG("data already exist in list.\n");
        return FAIL;
    }
    
    plistIndex = *plist;
    
    //find suitable positions to inserte.
    while(plistIndex->next!=NULL&&(plistIndex->data.id < pdata->data.id))
    {
        DEBUG("List id:%d, Data id:%d\n",plistIndex->data.id, pdata->data.id);
        //while() must usage plistIndex->next judegement.  or will use NULL point.
        plistIndex=plistIndex->next;
    }
    
    plistNode=plistIndex->next;
    plistIndex->next = pdata;
    pdata->next=plistNode;
    pdata->prev=plistIndex;
    
    return SUCCESS;
}

Ret_Status list_remove(list** plist,uint8 id)
{
    list* node=NULL;
    
    if(*plist==NULL)
    {
        ERROR("List handle error!");
        return FAIL;
    }
    
    node=list_findNode(*plist,id);
    
    //remove node is header, shoule special operation.
    if(node == *plist)
    {
        *plist=node->next;
        node->prev=NULL;
        node->next=NULL;
    }
    else if(!node->next)
    {
        node->prev->next=NULL;
    }    
    else
    {
        node->prev->next=node->next;
        node->prev=NULL;
        node->next=NULL;
    }
    
    free(node);
    
    return SUCCESS;
}

Ret_Status list_isEmpyt(list* plist)
{
    
}

Ret_Status list_dump(list* plist)
{
    assert(plist!=NULL);
    
    while(plist!=NULL)
    {
        printf("[%s] id:%d,age:%d,name:%s\n",__FUNCTION__,plist->data.id,plist->data.age,plist->data.name);
        plist=plist->next;
    }
    
    return SUCCESS;
}
